home *** CD-ROM | disk | FTP | other *** search
- /*
- File: ODMemoryCP.cpp
-
- Contains: xxx put contents here xxx
-
- Owned by: Nick Pilch
-
- Copyright: © 1996 by Apple Computer, Inc., all rights reserved.
-
- Change History (most recent first):
-
- <10> 11.09.1996 NP 1386074: Not using mimimum size for lower
- bound.
- <9> 17.07.1996 NP 1363849: Can't open desk accessories.
- <8> 15.07.1996 NP 1368246: OD Setup: The dialog font is
- hard-coded.
- <7> 12.07.1996 NP 1367619, 1365750: AreODProcessesRunning had
- break statements instead of continue
- statements.
- <6> 6/28/96 TJ Fixed Non-Debug Build.
- <5> 6/27/96 NP 10002: Launch time speedups.
- <4> 6/26/96 NP 10002: Launch time speedups.
- <3> 6/24/96 NP 10002: Launch time speedups
- <2> 6/23/96 NP 10002: Launch time speedups.
- <1> 6/21/96 NP first checked in
-
- To Do:
- */
-
- #ifndef ODMEMORYCP_H
- #include "ODMemoryCP.h"
- #endif
-
- #ifndef SIZERC_H
- #include "SIZERC.h"
- #endif
-
- #ifndef BETTERFINDFOLDER_H
- #include "BetterFindFolder.h"
- #endif
-
- #ifndef PREFSFILE_H
- #include "PrefsFile.h"
- #endif
-
- #ifndef ST_MACCLASSES_H
- #include "ST_MacClasses.h"
- #endif
-
- #ifndef _PROCESSSTUFF_
- #include "ProcessStuff.h"
- #endif
-
- #ifndef _ODPRCS_
- #include "ODPrcs.h"
- #endif
-
- #ifndef _SHELLDEF_
- #include "ShellDef.h"
- #endif
-
- #ifndef SOM_Module_OpenDoc_StdDefs_defined
- #include "StdDefs.xh"
- #endif
-
- #ifndef __DIALOGS__
- #include <Dialogs.h>
- #endif
-
- #ifndef __ICONS__
- #include <Icons.h>
- #endif
-
- #ifndef __MENUS__
- #include <Menus.h>
- #endif
-
- #ifndef __DEVICES__
- #include <Devices.h>
- #endif
-
- #ifndef __STRINGS__
- #include <Strings.h>
- #endif
-
- #ifndef __FONTS__
- #include <Fonts.h>
- #endif
-
- #ifndef __APPLEEVENTS__
- #include <AppleEvents.h>
- #endif
-
- #ifndef __TEXTUTILS__
- #include <TextUtils.h>
- #endif
-
- #ifndef __TOOLUTILS__
- #include <ToolUtils.h>
- #endif
-
- #define kMainDialogID 128
- #define kMenuBarID 128
- #define kAppleMenuID 1
- #define kAboutItem 1
- #define kFileMenuID 2
- #define kEditMenuID 3
-
- #define kNormalIconID 128
- #define kUpArrowIconID 129
- #define kDownArrowIconID 130
-
- enum {
- kOKButton = 1,
- kCancelButton, // 2
- kSizeText, // 3
- kArrowBottom, // 4
- kArrowTop, // 5
- kArrowControl, // 6
- kMiscText1, // 7 not used
- kMiscText2, // 8 not used
- kMiscText3, // 9 "K"
- kOKHilite // 10 not used
- };
-
- #define kAtSysStartupRadio 14
- #define kWhenFirstDocOpenedRadio 17
- #define kAtSysShutdownRadio 15
- #define kWhenLastDocClosedRadio 16
- #define kStartStopButton 13
- #define kProcessInfoText 20
-
- #define kSelected 1
-
- // STR
- #define kOpenDocIsStoppedID 128
- #define kOpenDocIsRunningID 129
- #define kStartID 130
- #define kStopID 131
- #define kOpenDocIsRunningNoStopID 132
-
- //#define kSleepTime 0xFFFFFFFF // Don't send any idle events.
- #define kSleepTime 60 //
-
- // CONSTANTS FOR MESSAGE SENDING
- #define kNoMessage 0 // used to see if the process returns noErr
- #define kStartAtSysStartup 1
- #define kStartAtFirstDocOpen 2
- #define kRunUntilQuitEvent 3
- #define kShutdownAtLastDocQuit 4
-
-
- pascal void MyUserItemProc (DialogPtr dlog, short item);
- UserItemUPP gUserItemUPP = NewUserItemProc (MyUserItemProc);
-
- void DisplayFinalErrors();
- void SetWindowPos();
- void WriteWindowPos(DialogPtr d);
- void CopyPascalString(StringPtr destStr, StringPtr srcStr);
- void DoDialogSetup(DialogPtr dialog);
- Boolean DoDialogHits(DialogPtr dialog, short itemHit);
- void ODSetupDebugStr(char* cString);
- void DoMemorySettingHits(DialogPtr dialog, short itemHit);
- void DoWhenToRunHits(DialogPtr dialog, short itemHit);
- void DoStopStartButtonHits(DialogPtr dialog, short itemHit);
- OSErr SendControlCall(DialogPtr dialog, ProcessSerialNumber* psn,
- long controlConstant);
- void SetPrefs(long controlConstant);
- void CheckForRunningSystemProcesses(DialogPtr dialog);
- void SetButtonRunState(DialogPtr dialog, Boolean odISRunning,
- Boolean odDocsAreRunning);
- OSErr LaunchSystemProcess(ProcessSerialNumber* psn);
- void AreODProcessesRunning(DialogPtr dialog, ProcessSerialNumber* psn,
- Boolean& odDocsAreRunning);
- void SetRunTextForRunningState(DialogPtr dialog, Boolean odDocsAreRunning);
- void SetRunItemsForRunningState(DialogPtr dialog, Boolean odDocsAreRunning);
- void SetRunItemsForStoppedState(DialogPtr dialog);
- void SetupRunItemsFirstTime(DialogPtr dialog, Boolean sysProcIsRunning,
- Boolean odDocsAreRunning);
- OSErr QuitSystemProcess(ProcessSerialNumber* psn);
- static pascal OSErr HandleQuit( const AppleEvent*, AppleEvent*, long );
-
- inline StringHandle GETSTRING(short resID)
- {
- #if ODDebug
- StringHandle h = GetString(resID);
- if (!h)
- DebugStr("\pGetString failed. I suggest 'es' now.");
- return h;
- #else
- return GetString(resID);
- #endif
- }
-
- inline void GETINDSTRING(StringPtr string, short resID, short index)
- {
-
- GetIndString(string, resID, index);
- #if ODDebug
- if (!string[0])
- DebugStr("\pGetIndString returned a NULL string. Is this right?");
- #endif
- }
- #if 0
- //------------------------------------------------------------------------------
- // CopyPascalString
- //------------------------------------------------------------------------------
-
- inline void CopyPascalString(StringPtr destStr, StringPtr srcStr)
- { BlockMoveData(srcStr, destStr, srcStr[0] + 1); }
- #endif /* 0 */
- //------------------------------------------------------------------------------
- // ODSetupDebugStr
- //------------------------------------------------------------------------------
-
- inline void ODSetupDebugStr(char* cString)
- { DebugStr(c2pstr(cString)); }
-
- //------------------------------------------------------------------------------
- // AttachUserItemProc
- //------------------------------------------------------------------------------
-
- static void AttachUserItemProc (DialogPtr dlog, short item, UserItemUPP proc)
- {
- Rect itemRect;
- short itemType;
- Handle itemHandle;
-
- GetDialogItem (dlog, item, &itemType, &itemHandle, &itemRect);
- SetDialogItem (dlog, item, itemType, (Handle) proc, &itemRect);
- }
-
- //------------------------------------------------------------------------------
- // PlotArrowIcon
- //------------------------------------------------------------------------------
-
- static void PlotArrowIcon(DialogPtr dlog, short item)
- {
- RgnHandle tempRgn = NewRgn();
- Handle icon;
- Rect arrowRect;
- short itemType;
- Handle itemHandle;
- GrafPtr savePort;
-
- GetPort(&savePort);
- SetPort(dlog);
- GetClip(tempRgn);
- GetDialogItem(dlog, kArrowControl, &itemType, &itemHandle, &arrowRect);
- ClipRect (&arrowRect);
- arrowRect.bottom = arrowRect.top + 32;
- arrowRect.right = arrowRect.left + 32;
-
- switch (item)
- {
- case kArrowControl:
- icon = GetResource('ICON', kNormalIconID);
- break;
- case kArrowTop:
- icon = GetResource('ICON', kUpArrowIconID);
- break;
- case kArrowBottom:
- icon = GetResource('ICON', kDownArrowIconID);
- break;
- }
-
- PlotIcon(&arrowRect, icon);
-
- SetClip(tempRgn);
- DisposeRgn(tempRgn);
- SetPort(savePort);
- }
-
- //------------------------------------------------------------------------------
- // MyUserItemProc
- //------------------------------------------------------------------------------
-
- pascal void MyUserItemProc (DialogPtr dlog, short item)
- {
- Rect itemRect;
- short itemType;
- Handle itemHandle;
-
- GetDialogItem (dlog, item, &itemType, &itemHandle, &itemRect);
-
- switch (item) {
-
- case kArrowControl :
- case kArrowTop :
- case kArrowBottom :
- PlotArrowIcon(dlog, item);
- break;
-
- case kOKHilite : // can be done automatically by Dialog Mgr.
- // PenNormal ();
- // PenSize (3, 3);
- // FrameRoundRect (&itemRect, 16, 16);
- break;
- }
- }
-
- //------------------------------------------------------------------------------
- // MenuChoice
- //------------------------------------------------------------------------------
-
- static Boolean MenuChoice (long menuMessage)
- {
- Boolean continueRunning = true;
-
- short whichMenu = menuMessage >> 16;
- short whichItem = menuMessage & 0x0000FFFF;
-
- switch (whichMenu) {
-
- case kAppleMenuID :
- if (whichItem == kAboutItem)
- {
- Handle h = GetResource('PICT', 128);
- if (h)
- Alert(kAboutBox, NULL);
- }
- else
- {
- Str255 name;
- GetMenuItemText (GetMenuHandle (kAppleMenuID), whichItem, name);
- OpenDeskAcc (name);
- }
- break;
-
- case kFileMenuID :
- continueRunning = false;
- break;
- }
-
- HiliteMenu (0);
- return continueRunning;
- }
-
- //------------------------------------------------------------------------------
- // InitToolbox
- //------------------------------------------------------------------------------
-
- static void InitToolbox ()
- {
- MaxApplZone ();
- InitGraf (&qd.thePort);
- InitFonts ();
- InitWindows ();
- InitMenus ();
- TEInit ();
- InitDialogs (nil);
-
- SetMenuBar (GetNewMBar (kMenuBarID));
- MenuHandle appleMenu = GetMenuHandle (kAppleMenuID);
- AppendResMenu (appleMenu, 'DRVR');
-
- InvalMenuBar ();
- }
-
- //------------------------------------------------------------------------------
- // SetDialogMemorySize
- //------------------------------------------------------------------------------
-
- static void SetDialogMemorySize (DialogPtr dlog, Size size)
- {
- long kilobytes = size / 1024;
- Str255 text;
- Rect itemRect;
- short itemType;
- Handle itemHandle;
-
- GetDialogItem (dlog, kSizeText, &itemType, &itemHandle, &itemRect);
-
- NumToString (kilobytes, text);
- SetDialogItemText (itemHandle, text);
- }
-
- //------------------------------------------------------------------------------
- // main
- //------------------------------------------------------------------------------
-
- OSErr gSetDefaultSizeError = noErr;
- short gMyResFileRefNum;
- Size gSize = kDocStubDefaultSize;
- FSSpec gPrefsFileSpec;
-
- Boolean gRunning = true;
-
- void main()
- {
- gMyResFileRefNum = CurResFile();
-
- InitToolbox ();
-
- AEEventHandlerUPP handlerUPP = NewAEEventHandlerProc(HandleQuit);
- if (!handlerUPP ||
- AEInstallEventHandler(kCoreEventClass, kAEQuitApplication,
- handlerUPP, 0, false))
- StopAlert(kFatalStartupError, NULL);
-
- // Try to create/open a prefs file to work with.
- short permissions = fsRdWrPerm;
- short prefs = OpenODPrefsResFile (true, permissions);
- if (prefs < 0)
- {
- CautionAlert(kCantWritePreferencesID, NULL);
- permissions = fsRdPerm;
- prefs = OpenODPrefsResFile(true, permissions);
- }
- CloseResFile(prefs);
-
- // ODSetUpPrefs* prefsAccessor = new ODSetUpPrefs(prefs, permissions);
-
- SetWindowPos(); // DO THIS BEFORE GetNewDialog
- DialogPtr d = GetNewDialog (kMainDialogID, nil, (WindowPtr) -1);
- if (!d)
- StopAlert(kFatalStartupError, NULL);
-
- // Hard-coded values. I hope it's OK for the localizers, but probably not.
- // I tried to make Resorcerer use an ictb, but it was hard to get it to
- // work right.
- long scriptSmallFontSize;
- scriptSmallFontSize = GetScriptVariable(smSystemScript,
- smScriptSmallFondSize);
- d->txFont = HiWord(scriptSmallFontSize);
- d->txSize = LoWord(scriptSmallFontSize);
- // d->txFont = geneva;
- // d->txSize = 9;
-
- DoDialogSetup(d);
-
- ShowWindow (d);
- InitCursor ();
-
- do
- {
- EventRecord theEvent;
-
- CheckForRunningSystemProcesses(d);
-
- if (WaitNextEvent (everyEvent, &theEvent, kSleepTime, nil))
- {
- if (IsDialogEvent (&theEvent))
- {
- short itemHit;
- DialogPtr theDialog;
-
- if (DialogSelect (&theEvent, &theDialog, &itemHit) &&
- (theDialog == d))
- gRunning = DoDialogHits(d, itemHit);
- else
- {
- if (theEvent.what == keyDown || theEvent.what == autoKey)
- {
- if (theEvent.modifiers & cmdKey)
- gRunning = MenuChoice(MenuKey
- (theEvent.message & charCodeMask));
- }
- if (theEvent.what == kHighLevelEvent)
- AEProcessAppleEvent(&theEvent);
- }
- }
- else
- {
- switch (theEvent.what)
- {
- case mouseDown :
- {
- WindowPtr win;
- short part = FindWindow (theEvent.where, &win);
-
- switch (part)
- {
- case inMenuBar :
- gRunning = MenuChoice (MenuSelect (theEvent.where));
- break;
-
- case inSysWindow :
- SystemClick (&theEvent, win);
- break;
-
- case inDrag :
- {
- Rect limitRect = { -20000, -20000, 20000, 20000 };
- DragWindow (win, theEvent.where, &limitRect);
- }
- break;
-
- case inGoAway :
- if (TrackGoAway (win, theEvent.where))
- gRunning = false;
- break;
- }
- }
- break;
-
- case keyDown :
- case autoKey :
- if (theEvent.modifiers & cmdKey)
- gRunning = MenuChoice (MenuKey (theEvent.message & charCodeMask));
- break;
-
- case kHighLevelEvent:
- AEProcessAppleEvent(&theEvent);
- }
- }
- }
- }
- while (gRunning);
-
- DisplayFinalErrors();
- WriteWindowPos(d);
- // delete prefsAccessor;
- // CloseResFile(prefs);
- DisposeDialog (d);
- }
-
- //------------------------------------------------------------------------------
- // DisplayFinalErrors
- //------------------------------------------------------------------------------
-
- void DisplayFinalErrors()
- {
- if (gSetDefaultSizeError)
- CautionAlert(kCantWriteDefaultSizeID, NULL);
- }
-
- //------------------------------------------------------------------------------
- // DoDialogSetup
- //------------------------------------------------------------------------------
-
- void DoDialogSetup(DialogPtr dialog)
- {
- Rect itemRect;
- short itemType;
- Handle itemHandle;
- Str255 tempString;
- FSSpec ignore;
- ODSetUpPrefs prefs(-1, 0);
-
- AttachUserItemProc (dialog, kArrowControl, gUserItemUPP);
- AttachUserItemProc (dialog, kArrowTop, gUserItemUPP);
- AttachUserItemProc (dialog, kArrowBottom, gUserItemUPP);
- AttachUserItemProc (dialog, kOKHilite, gUserItemUPP);
-
- if (prefs.GetDefaultSize(gSize))
- ODSetupDebugStr("Unexpectedly got an error from GetODDefaultSize");
- else
- SetDialogMemorySize(dialog, gSize);
-
- // SET UP START BUTTON AND BUTTON TEXT
- // THIS WILL SET THE DEFAULT "STOPPED" STATE
- GetDialogItem(dialog, kProcessInfoText, &itemType, &itemHandle,
- &itemRect);
- CopyPascalString(tempString, *GETSTRING(kOpenDocIsStoppedID));
- SetDialogItemText(itemHandle, tempString);
-
- // THIS WILL CHANGE IT IF IT NEEDS TO
- CheckForRunningSystemProcesses(dialog);
-
- // STARTUP CHOICES
- if (OurAliasFileIsInStartupFolder(&ignore))
- GetDialogItem(dialog, kAtSysStartupRadio, &itemType, &itemHandle,
- &itemRect);
- else
- GetDialogItem(dialog, kWhenFirstDocOpenedRadio, &itemType, &itemHandle,
- &itemRect);
- SetControlValue((ControlHandle)itemHandle, kSelected);
-
- // SHUTDOWN CHOICES
- if (prefs.GetRunTilSysShutdown())
- GetDialogItem(dialog, kAtSysShutdownRadio, &itemType, &itemHandle,
- &itemRect);
- else
- GetDialogItem(dialog, kWhenLastDocClosedRadio, &itemType, &itemHandle,
- &itemRect);
- SetControlValue((ControlHandle)itemHandle, kSelected);
- }
-
- //------------------------------------------------------------------------------
- // DoDialogHits
- //
- // Returns whether we should keep gRunning.
- //------------------------------------------------------------------------------
-
- Boolean DoDialogHits(DialogPtr dialog, short itemHit)
- {
- Boolean shouldKeepRunning = true;
-
- switch (itemHit)
- {
- case kCancelButton :
- // sz = originalSize; // used to have an OK, Cancel interface.
- case kOKButton :
- shouldKeepRunning = false;
- break;
-
- case kArrowBottom :
- case kArrowTop :
- DoMemorySettingHits(dialog, itemHit);
- break;
-
- case kAtSysStartupRadio :
- case kWhenFirstDocOpenedRadio :
- case kAtSysShutdownRadio :
- case kWhenLastDocClosedRadio :
- DoWhenToRunHits(dialog, itemHit);
- break;
-
- case kStartStopButton :
- DoStopStartButtonHits(dialog, itemHit);
- break;
- }
-
- return shouldKeepRunning;
- }
-
- //------------------------------------------------------------------------------
- // DoWhenToRunHits
- //------------------------------------------------------------------------------
-
- void DoWhenToRunHits(DialogPtr dialog, short itemHit)
- {
- Rect itemRect;
- short itemType;
- Handle itemHandle;
- ProcessSerialNumber psn = {0, kNoProcess};
- ODSetUpPrefs prefs(-1, 0);
- Boolean settingPrefsWorked;
- Boolean sendingMessageWorked;
-
- // FIRST JUST HANDLE THE RADIO BUTTON SWITCHING
- switch (itemHit)
- {
- case kAtSysStartupRadio :
- GetDialogItem(dialog, kAtSysStartupRadio, &itemType, &itemHandle,
- &itemRect);
- if (GetControlValue((ControlHandle)itemHandle) != kSelected)
- {
- // PLACE ALIAS IN STARTUP ITEMS FOLDER
- if (AliasSystemProcessToStartupFolder())
- {
- SetControlValue((ControlHandle)itemHandle, kSelected);
- GetDialogItem(dialog, kWhenFirstDocOpenedRadio, &itemType,
- &itemHandle, &itemRect);
- SetControlValue((ControlHandle)itemHandle, !kSelected);
- }
- }
- break;
- case kWhenFirstDocOpenedRadio :
- GetDialogItem(dialog, kWhenFirstDocOpenedRadio, &itemType, &itemHandle,
- &itemRect);
- if (GetControlValue((ControlHandle)itemHandle) != kSelected)
- {
- // REMOVE ALIAS FROM STARTUP ITEMS FOLDER
- if (RemoveAliasToSystemProcessFromStartupFolder())
- {
- SetControlValue((ControlHandle)itemHandle, kSelected);
- GetDialogItem(dialog, kAtSysStartupRadio, &itemType,
- &itemHandle, &itemRect);
- SetControlValue((ControlHandle)itemHandle, !kSelected);
- }
- }
- break;
- case kAtSysShutdownRadio :
- GetDialogItem(dialog, kAtSysShutdownRadio, &itemType, &itemHandle,
- &itemRect);
- if (GetControlValue((ControlHandle)itemHandle) != kSelected)
- {
- // SET PREFERENCES AND NOTIFY ANY RUNNING SYSTEM PROCESSES
- settingPrefsWorked = !prefs.SetRunTilSysShutdown(true);
- sendingMessageWorked = !SendControlCall(dialog, &psn,
- kRunUntilQuitEvent);
- if (!settingPrefsWorked && !sendingMessageWorked)
- CautionAlert(kCouldntSetShutDownPreference, NULL);
- else
- {
- SetControlValue((ControlHandle)itemHandle, kSelected);
- GetDialogItem(dialog, kWhenLastDocClosedRadio, &itemType,
- &itemHandle, &itemRect);
- SetControlValue((ControlHandle)itemHandle, !kSelected);
- }
- }
- break;
- case kWhenLastDocClosedRadio :
- GetDialogItem(dialog, kWhenLastDocClosedRadio, &itemType, &itemHandle,
- &itemRect);
- if (GetControlValue((ControlHandle)itemHandle) != kSelected)
- {
- // SET PREFERENCES AND NOTIFY ANY RUNNING SYSTEM PROCESSES
- settingPrefsWorked = !prefs.SetRunTilSysShutdown(false);
- sendingMessageWorked = !SendControlCall(dialog, &psn,
- kShutdownAtLastDocQuit);
- if (!settingPrefsWorked && !sendingMessageWorked)
- CautionAlert(kCouldntSetShutDownPreference, NULL);
- else
- {
- SetControlValue((ControlHandle)itemHandle, kSelected);
- GetDialogItem(dialog, kAtSysShutdownRadio, &itemType,
- &itemHandle, &itemRect);
- SetControlValue((ControlHandle)itemHandle, !kSelected);
- }
- }
- break;
- }
- }
-
- //------------------------------------------------------------------------------
- // SendControlCall
- //
- // This function contains logic about whether or not to bother sending the
- // control message at all!
- //
- // Send a message to the system process.
- //
- // The psn parameter is only needed for certain constants. If furnished, it
- // will be used, but if psn.lowLongOfPSN == kNoProcess, then we will try
- // to find and launch the system process.
- //
- // kNoMessage - psn is required.
- // kStartAtSysStartup - this is currently not supported because it's not
- // needed
- // kStartAtFirstDocOpen - this is currently not supported because it's not
- // needed
- // kRunUntilQuitEvent - psn is not required.
- // kShutdownAtLastDocQuit - psn is not required.
- //------------------------------------------------------------------------------
-
- #define CATCHERROR(x) error = x; if (error) goto cleanup;
-
- OSErr SendControlCall(DialogPtr dialog, ProcessSerialNumber* psn,
- long controlConstant)
- {
- OSErr error = noErr;
- Boolean odDocsAreRunning;
- Boolean sysProcIsRunning;
-
- // IF WE WERE NOT GIVEN A PSN TO USE, LOOK FOR THE SYSTEM PROCESS AND LAUNCH
- // IT IF NECESSARY.
- if (psn->lowLongOfPSN == kNoProcess)
- {
- if (controlConstant == kRunUntilQuitEvent
- || controlConstant == kShutdownAtLastDocQuit)
- {
- AreODProcessesRunning(dialog, psn, odDocsAreRunning);
- sysProcIsRunning = !(psn->lowLongOfPSN == kNoProcess);
- // SYSTEM PROCESS MAY NOT BE RUNNING (USER MAY HAVE LAUNCHED
- // LAUNCHER INSTEAD). SO MUST LAUNCH SYSTEM PROCESS WHEN WE WANT
- // OPENDOC TO STAY LOADED FOREVER.
- if (odDocsAreRunning
- && (controlConstant == kRunUntilQuitEvent)
- && !sysProcIsRunning)
- error = LaunchSystemProcess(psn);
- }
- }
-
- if (!error)
- {
- AEAddressDesc address = {typeNull, NULL};
- AppleEvent message = {typeNull, NULL};
- AppleEvent reply = {typeNull, NULL};
-
- CATCHERROR(AECreateDesc(typeProcessSerialNumber, (Ptr)psn, sizeof(*psn),
- &address));
- CATCHERROR(AECreateAppleEvent(kODShellSignature, kSysProcControlEventID,
- &address, kAutoGenerateReturnID, kAnyTransactionID,
- &message));
- CATCHERROR(AEPutParamPtr(&message, kControlMessageKeyword, typeInteger,
- (Ptr)&controlConstant,
- sizeof(controlConstant)));
- CATCHERROR(AESend(&message, &reply,
- kAENoReply + kAENeverInteract + kAEDontRecord,
- kAEHighPriority, kAEDefaultTimeout,
- (AEIdleUPP)kODNULL, (AEFilterUPP)kODNULL));
-
- cleanup:
- AEDisposeDesc(&address);
- AEDisposeDesc(&message);
- AEDisposeDesc(&reply);
- }
-
- return error;
- }
-
- //------------------------------------------------------------------------------
- // DoMemorySettingHits
- //
- // There's a small chance that we might hit a window and do that opposite of
- // what the button says.
- //------------------------------------------------------------------------------
-
- void DoStopStartButtonHits(DialogPtr dialog, short itemHit)
- {
- ProcessSerialNumber psn;
- Boolean odDocsAreRunning;
- Boolean systemProcessIsRunning;
-
- AreODProcessesRunning(dialog, &psn, odDocsAreRunning);
- systemProcessIsRunning = !(psn.lowLongOfPSN == kNoProcess);
- if (systemProcessIsRunning)
- {
- if (QuitSystemProcess(&psn))
- CautionAlert(kCouldntShutDownOpenDoc, NULL);
- }
- else
- {
- if (LaunchSystemProcess(&psn))
- CautionAlert(kCouldntStartupOpenDoc, NULL);
- }
- }
-
- //------------------------------------------------------------------------------
- // DoMemorySettingHits
- //------------------------------------------------------------------------------
-
- #define kSizeIncrement (32 * 1024L)
- #define kMaximumSize (1024L * 1024L * 64)
-
- void DoMemorySettingHits(DialogPtr dialog, short itemHit)
- {
- short itemType;
- Handle itemHandle;
- Rect arrowRect;
- Point mousePoint;
- long ignore;
- GrafPtr savePort;
- ODSetUpPrefs prefs(-1, 0);
-
- switch (itemHit)
- {
- case kArrowBottom :
- GetDialogItem(dialog, kArrowBottom, &itemType,
- &itemHandle, &arrowRect);
- PlotArrowIcon(dialog, itemHit);
- GetPort(&savePort);
- SetPort(dialog);
- do
- {
- GetMouse(&mousePoint);
- if (PtInRect(mousePoint, &arrowRect))
- {
- gSize -= kSizeIncrement;
- if (gSize < kDocStubMinHeapSize)
- gSize = kDocStubMinHeapSize;
- else
- SetDialogMemorySize (dialog, gSize);
- Delay(8, &ignore);
- }
- }
- while (StillDown());
- SetPort(savePort);
- PlotArrowIcon(dialog, kArrowControl);
- if(prefs.SetDefaultSize(gSize))
- gSetDefaultSizeError = 1; // dummy value for now
- break;
-
- case kArrowTop :
- GetDialogItem(dialog, kArrowTop, &itemType,
- &itemHandle, &arrowRect);
- PlotArrowIcon(dialog, itemHit);
- GetPort(&savePort);
- SetPort(dialog);
- do
- {
- GetMouse(&mousePoint);
- if (PtInRect(mousePoint, &arrowRect))
- {
- gSize += kSizeIncrement;
- if (gSize > kMaximumSize)
- gSize = kMaximumSize;
- else
- SetDialogMemorySize(dialog, gSize);
- Delay(8, &ignore);
- }
- }
- while (StillDown());
- SetPort(savePort);
- PlotArrowIcon(dialog, kArrowControl);
- if(prefs.SetDefaultSize(gSize))
- gSetDefaultSizeError = 1; // dummy value for now
- break;
- }
- }
-
- //------------------------------------------------------------------------------
- // SetWindowPos
- //------------------------------------------------------------------------------
-
- void SetWindowPos()
- {
- Rect dialogRect;
- RgnHandle windowRgn = NewRgn();
- RgnHandle intersectRgn = NewRgn();
-
- short saveResFile = CurResFile();
- UseResFile(gMyResFileRefNum);
-
- DialogTHndl hResource = (DialogTHndl)Get1Resource('DLOG', kMainDialogID);
-
- UseResFile(saveResFile);
-
- dialogRect = (**hResource).boundsRect;
-
- dialogRect.top -= 18; // window title bar height.
-
- RectRgn(windowRgn, &dialogRect);
- SectRgn(windowRgn, GetGrayRgn(), intersectRgn);
- if (!EqualRgn(windowRgn, intersectRgn))
- {
- short height = dialogRect.bottom - dialogRect.top;
- short width = dialogRect.right - dialogRect.left;
-
- dialogRect.top = 100;
- dialogRect.left = 100;
- dialogRect.bottom = 100 + height;
- dialogRect.right = 100 + width;
-
- (**hResource).boundsRect = dialogRect;
- }
-
- DisposeRgn(windowRgn);
- DisposeRgn(intersectRgn);
- }
-
- //------------------------------------------------------------------------------
- // WriteWindowPos
- //------------------------------------------------------------------------------
-
- void WriteWindowPos(DialogPtr dialog)
- {
- Rect dialogRect;
- short saveResFile = CurResFile();
-
- UseResFile(gMyResFileRefNum);
-
- DialogTHndl hResource = (DialogTHndl)Get1Resource('DLOG', kMainDialogID);
-
- // GOT THIS INFO FROM INSPECTION IN THE DEBUGGER
- dialogRect.top = -dialog->portBits.bounds.top;
- dialogRect.left = -dialog->portBits.bounds.left;
- dialogRect.bottom = dialogRect.top + dialog->portRect.bottom;
- dialogRect.right = dialogRect.left + dialog->portRect.right;
-
- (**hResource).boundsRect = dialogRect;
- ChangedResource((Handle)hResource);
- WriteResource((Handle)hResource);
-
- UseResFile(saveResFile);
- }
-
- //------------------------------------------------------------------------------
- // CheckForRunningSystemProcesses
- //
- // The system process can have kODShellSignature or kODSystemProcessSignature
- // signatures. If we encounter a kODShellSignature app, we ask it if
- // it is the right one. We could also look for the special resource.
- //
- // Will return a valid ProcessSerialNumber if a system process is running,
- // otherwise, psn.lowLongOfPSN is set to kNoProcess.
- //------------------------------------------------------------------------------
-
- void CheckForRunningSystemProcesses(DialogPtr dialog)
- {
- ProcessSerialNumber psn;
- Boolean odDocsAreRunning;
- Boolean systemProcessIsRunning;
-
- AreODProcessesRunning(dialog, &psn, odDocsAreRunning);
- systemProcessIsRunning = !(psn.lowLongOfPSN == kNoProcess);
-
- if (odDocsAreRunning && !systemProcessIsRunning)
- // SHOULD TRY TO LAUNCH SYSTEM PROCESS NOW?
- // NO. WAIT UNTIL I NEED TO
- ;
-
- if (systemProcessIsRunning || odDocsAreRunning)
- SetButtonRunState(dialog, true, odDocsAreRunning);
- else
- SetButtonRunState(dialog, false, odDocsAreRunning);
-
- }
-
- //------------------------------------------------------------------------------
- // AreODProcessesRunning
- //
- // The system process can have kODShellSignature or kODSystemProcessSignature
- // signatures. If we encounter a kODShellSignature app, we ask it if
- // it is the right one. We could also look for the special resource.
- //
- // Will return a valid ProcessSerialNumber if a system process is running,
- // otherwise, psn.lowLongOfPSN is set to kNoProcess.
- //------------------------------------------------------------------------------
-
- void AreODProcessesRunning(DialogPtr dialog, ProcessSerialNumber* psn,
- Boolean& odDocsAreRunning)
- {
- ProcessInfoRec procInfo;
- OSErr error = noErr;
- FSSpec procSpec;
- Boolean systemProcessIsRunning = false;
- ProcessSerialNumber iteratorPSN; // used to iterate only.
-
- odDocsAreRunning = false;
-
- psn->highLongOfPSN = 0;
- psn->lowLongOfPSN = kNoProcess;
- iteratorPSN.highLongOfPSN = 0;
- iteratorPSN.lowLongOfPSN = kNoProcess;
-
- procInfo.processInfoLength = sizeof(procInfo);
- procInfo.processName = NULL;
- procInfo.processAppSpec = &procSpec;
-
- while (error != procNotFound)
- {
- error = GetNextProcess(&iteratorPSN);
- if (!error)
- error = GetProcessInformation(&iteratorPSN, &procInfo);
- if (!error)
- {
- FInfo finderInfo;
-
- error = FSpGetFInfo(&procSpec, &finderInfo);
- if (!error)
- {
- if (finderInfo.fdCreator == kODSystemProcessSignature)
- {
- *psn = procInfo.processNumber;
- systemProcessIsRunning = true;
- continue;
- }
- else if (finderInfo.fdCreator == kODShellSignature
- && finderInfo.fdType == 'APPL')
- {
- if (!SendControlCall(dialog, &procInfo.processNumber,
- kNoMessage))
- {
- *psn = procInfo.processNumber;
- systemProcessIsRunning = true;
- continue;
- }
- }
- if (!odDocsAreRunning &&
- PlatformFile::IsOpenDocDocument(finderInfo.fdType,
- finderInfo.fdCreator))
- odDocsAreRunning = true;
- }
- }
- }
- }
-
- //------------------------------------------------------------------------------
- // SetButtonRunState
- //
- // gSysProcIsRunning is set as a side effect here. Gross, but it allows us to
- // use gSysProcIsRunning as "previous state" flag that we can check to make
- // sure we don't redraw the button more than we have to. Similarly with
- // gODDocsAreRunning
- //------------------------------------------------------------------------------
- #if 0
- Boolean gSysProcIsRunning = false;
- Boolean gODDocsAreRunning = false;
- Boolean gFirstTimeThrough = true;
-
- void SetButtonRunState(DialogPtr dialog, Boolean sysProcIsRunning,
- Boolean odDocsAreRunning)
- {
- short itemType;
- Handle itemHandle;
- Rect itemRect;
- Str255 tempString;
- const short kActive = 0;
-
- if (sysProcIsRunning && odDocsAreRunning)
- if (!sysProcIsRunning && odDocsAreRunning)
-
- if (sysProcIsRunning && !odDocsAreRunning)
-
- if (!sysProcIsRunning && !odDocsAreRunning)
-
- if (gSysProcIsRunning)
- {
- if (!sysProcIsRunning)
- {
- // SET TO STOPPED STATE
- gSysProcIsRunning = false;
-
- // BUTTON
- GetDialogItem(dialog, kStartStopButton, &itemType, &itemHandle,
- &itemRect);
- CopyPascalString(tempString, *GETSTRING(kStartID));
- SetControlTitle((ControlHandle)itemHandle, tempString);
- HiliteControl((ControlHandle)itemHandle, kActive);
-
- // TEXT
- GetDialogItem(dialog, kProcessInfoText, &itemType, &itemHandle,
- &itemRect);
- CopyPascalString(tempString, *GETSTRING(kOpenDocIsStoppedID));
- SetDialogItemText(itemHandle, tempString);
- }
- }
- else
- {
- if (sysProcIsRunning)
- {
- // SET TO RUNNING STATE
- gSysProcIsRunning = true;
-
- // BUTTON
- GetDialogItem(dialog, kStartStopButton, &itemType, &itemHandle,
- &itemRect);
- CopyPascalString(tempString, *GETSTRING(kStopID));
- SetControlTitle((ControlHandle)itemHandle, tempString);
-
- if (odDocsAreRunning)
- HiliteControl((ControlHandle)itemHandle, kControlInactivePart);
- else
- HiliteControl((ControlHandle)itemHandle, kActive);
-
- GetDialogItem(dialog, kProcessInfoText, &itemType, &itemHandle,
- &itemRect);
-
- // TEXT
- if (odDocsAreRunning && !gODDocsAreRunning)
- {
- gODDocsAreRunning = true;
-
- CopyPascalString(tempString,
- *GETSTRING(kOpenDocIsRunningNoStopID));
- SetDialogItemText(itemHandle, tempString);
- }
- else if (!odDocsAreRunning && gODDocsAreRunning)
- {
- CopyPascalString(tempString,
- *GETSTRING(kOpenDocIsRunningID));
- SetDialogItemText(itemHandle, tempString);
- }
- }
- }
- gFirstTimeThrough = false;
- }
- #endif /* 0 */
-
- //------------------------------------------------------------------------------
- // SetupRunItemsFirstTime
- //------------------------------------------------------------------------------
-
- void SetupRunItemsFirstTime(DialogPtr dialog, Boolean sysProcIsRunning,
- Boolean odDocsAreRunning)
- {
- if (!sysProcIsRunning && !odDocsAreRunning)
- SetRunItemsForStoppedState(dialog);
- else
- SetRunItemsForRunningState(dialog, odDocsAreRunning);
- }
-
- //------------------------------------------------------------------------------
- // SetRunTextForRunningState
- //------------------------------------------------------------------------------
-
- void SetRunTextForRunningState(DialogPtr dialog, Boolean odDocsAreRunning)
- {
- short itemType;
- Rect itemRect;
- Handle itemHandle;
- Str255 tempString;
- const short kActive = 0;
-
- GetDialogItem(dialog, kProcessInfoText, &itemType, &itemHandle,
- &itemRect);
- if (odDocsAreRunning)
- {
- CopyPascalString(tempString,
- *GETSTRING(kOpenDocIsRunningNoStopID));
- SetDialogItemText(itemHandle, tempString);
- }
- else
- {
- CopyPascalString(tempString,
- *GETSTRING(kOpenDocIsRunningID));
- SetDialogItemText(itemHandle, tempString);
- }
- }
-
- //------------------------------------------------------------------------------
- // SetRunItemsForRunningState
- //------------------------------------------------------------------------------
-
- void SetRunItemsForRunningState(DialogPtr dialog, Boolean odDocsAreRunning)
- {
- short itemType;
- Handle itemHandle;
- Rect itemRect;
- Str255 tempString;
- const short kActive = 0;
-
- // BUTTON
- GetDialogItem(dialog, kStartStopButton, &itemType, &itemHandle,
- &itemRect);
- CopyPascalString(tempString, *GETSTRING(kStopID));
- SetControlTitle((ControlHandle)itemHandle, tempString);
-
- if (odDocsAreRunning)
- HiliteControl((ControlHandle)itemHandle, kControlInactivePart);
- else
- HiliteControl((ControlHandle)itemHandle, kActive);
-
- // TEXT
- SetRunTextForRunningState(dialog, odDocsAreRunning);
- }
-
- //------------------------------------------------------------------------------
- // SetRunItemsForStoppedState
- //------------------------------------------------------------------------------
-
- void SetRunItemsForStoppedState(DialogPtr dialog)
- {
- short itemType;
- Handle itemHandle;
- Rect itemRect;
- Str255 tempString;
- const short kActive = 0;
-
- // BUTTON
- GetDialogItem(dialog, kStartStopButton, &itemType, &itemHandle,
- &itemRect);
- CopyPascalString(tempString, *GETSTRING(kStartID));
- SetControlTitle((ControlHandle)itemHandle, tempString);
- HiliteControl((ControlHandle)itemHandle, kActive);
-
- // TEXT
- GetDialogItem(dialog, kProcessInfoText, &itemType, &itemHandle,
- &itemRect);
- CopyPascalString(tempString, *GETSTRING(kOpenDocIsStoppedID));
- SetDialogItemText(itemHandle, tempString);
- }
-
- //------------------------------------------------------------------------------
- // SetButtonRunState
- //
- // Using a transition table so that I only make changes to the dialog when I
- // need to.
- //------------------------------------------------------------------------------
-
- enum
- {
- kSysProcIsRunning = ( 1 << 0 ), // used whenever sysProcIsRunning is true
- kODDocsAreRunning = ( 1 << 1 ), // used whenver odDocsAreRunning is true
- kFirstTimeThrough = ( 1 << 2 ) // only used in initialization of global
- };
-
- int gODOldSysRunState = kFirstTimeThrough; // only time this bit is used
-
- void SetButtonRunState(DialogPtr dialog, Boolean sysProcIsRunning,
- Boolean odDocsAreRunning)
- {
- // turn on kSysProcIsRunning bit if sysProcIsRunning is true:
- int newRunState = ( sysProcIsRunning ) ? kSysProcIsRunning : 0;
-
- // turn on kODDocsAreRunning bit if odDocsAreRunning is true:
- if ( odDocsAreRunning )
- newRunState |= kODDocsAreRunning;
-
- // Note that the kFirstTimeThrough bit is never set in newRunState.
-
- // record whether the kFirstTimeThrough bit is set in gODOldSysRunState:
- Boolean firstTime = ( gODOldSysRunState & kFirstTimeThrough ) != 0;
-
- if (firstTime)
- {
- // this happens only once.
-
- SetupRunItemsFirstTime(dialog, sysProcIsRunning, odDocsAreRunning);
- }
- else if ( /*firstTime ||*/ newRunState != gODOldSysRunState )
- {
- // anything changed?
-
- // ~kFirstTimeThrough is a mask of all ones with a zero at ( 1 << 2 )
- // we are removing the kFirstTimeThrough bit from gODOldSysRunState here:
- int oldWithoutFirstTime = ( gODOldSysRunState & ~kFirstTimeThrough );
-
- // now build a 4 bit integer with the top two bits containing old state:
- int oldAndNewState = ( oldWithoutFirstTime << 2 ) | newRunState;
-
- // table to examine all possible transitions from old to new state:
- switch ( oldAndNewState )
- {
- // gODOldSysRunState == !kODDocsAreRunning && !kSysProcIsRunning
- case 0x0: // 00 -> 00 => should not occur (huh?)
- ODSetupDebugStr("hit a should not occur case");
- break;
-
- case 0x1: // 00 -> 01 => no docs running, but sys proc running
- // (NOW RUNNING, CAN STOP)
- SetRunItemsForRunningState(dialog, odDocsAreRunning);
- break;
- case 0x2: // 00 -> 10 => docs running now, but no sys proc
- // (NOW RUNNING, CAN'T STOP)
- SetRunItemsForRunningState(dialog, odDocsAreRunning);
- break;
- case 0x3: // 00 -> 11 => both running (NOW RUNNING, CAN'T STOP)
- SetRunItemsForRunningState(dialog, odDocsAreRunning);
- break;
-
- // gODOldSysRunState == !kODDocsAreRunning && kSysProcIsRunning
- case 0x4: // 01 -> 00 => (NOTHING RUNNING)
- SetRunItemsForStoppedState(dialog);
- break;
- case 0x5: // 01 -> 01 => should not occur (huh?)
- ODSetupDebugStr("hit a should not occur case 01 -> 01");
- break;
- case 0x6: // 01 -> 10 => docs running now, no sys proc
- // (CAN'T STOP)
- // SetRunTextForRunningState(dialog, odDocsAreRunning);
- SetRunItemsForRunningState(dialog, odDocsAreRunning);
- break;
- case 0x7: // 01 -> 11 => docs running now (CAN'T STOP)
- // SetRunTextForRunningState(dialog, odDocsAreRunning);
- SetRunItemsForRunningState(dialog, odDocsAreRunning);
- break;
-
- // gODOldSysRunState == kODDocsAreRunning && !kSysProcIsRunning
- case 0x8: // 10 -> 00 => (NOTHING RUNNING)
- SetRunItemsForStoppedState(dialog);
- break;
- case 0x9: // 10 -> 01 => docs not running, but sysproc is
- // (CAN STOP)
- // SetRunTextForRunningState(dialog, odDocsAreRunning);
- SetRunItemsForRunningState(dialog, odDocsAreRunning);
- break;
- case 0xA: // 10 -> 10 => should not occur (huh?)
- ODSetupDebugStr("hit a should not occur case 10 -> 10");
- break;
- case 0xB: // 10 -> 11 => docs running and now sys proc (NO-OP)
- // SetRunTextForRunningState(dialog, odDocsAreRunning);
- SetRunItemsForRunningState(dialog, odDocsAreRunning);
- break;
-
- // gODOldSysRunState == kODDocsAreRunning && kSysProcIsRunning
- case 0xC: // 11 -> 00 => (NOTHING RUNNING)
- SetRunItemsForStoppedState(dialog);
- break;
- case 0xD: // 11 -> 01 => docs no longer running (CAN STOP)
- // SetRunTextForRunningState(dialog, odDocsAreRunning);
- SetRunItemsForRunningState(dialog, odDocsAreRunning);
- break;
- case 0xE: // 11 -> 10 => sys proc no longer running (NO-OP)
- break;
- case 0xF: // 11 -> 11 => should not occur (huh?)
- ODSetupDebugStr("hit a should not occur case 11 -> 11");
- break;
- default:
- ODSetupDebugStr("default case.");
- // huh?
- break;
- }
- }
-
- gODOldSysRunState = newRunState; // always update old with new state
- // gODOldSysRunState never has kFirstTimeThrough bit set again
- }
-
- //------------------------------------------------------------------------------
- // LaunchSystemProcess
- //------------------------------------------------------------------------------
-
- OSErr LaunchSystemProcess(ProcessSerialNumber* psn)
- {
- OSErr error;
- FSSpec sysProcSpec;
- FInfo finderInfo;
-
- error = SystemProcessFileSpecFromName(&sysProcSpec);
-
- // just make call to verify the existence of the file
- if (!error)
- error = FSpGetFInfo(&sysProcSpec, &finderInfo);
-
- if (error)
- error = SystemProcessFileSpecFromSecretResource(&sysProcSpec);
-
- if (!error)
- {
- LaunchParamBlockRec launchPB;
-
- launchPB.launchBlockID = extendedBlock;
- launchPB.launchEPBLength = extendedBlockLen;
- // HOW ABOUT OTHER FLAGS?
- launchPB.launchControlFlags = launchContinue
- | launchNoFileFlags
- | launchDontSwitch;
- launchPB.launchAppSpec = &sysProcSpec;
- launchPB.launchAppParameters = NULL;
-
- error = LaunchApplication(&launchPB);
- if (!error)
- *psn = launchPB.launchProcessSN;
- }
-
- return error;
- }
-
- //------------------------------------------------------------------------------
- // QuitSystemProcess
- //------------------------------------------------------------------------------
-
- OSErr QuitSystemProcess(ProcessSerialNumber* psn)
- {
- OSErr error;
- AEAddressDesc address = {typeNull, NULL};
- AppleEvent message = {typeNull, NULL};
- AppleEvent reply = {typeNull, NULL};
-
- CATCHERROR(AECreateDesc(typeProcessSerialNumber, (Ptr)psn, sizeof(*psn),
- &address));
- CATCHERROR(AECreateAppleEvent(kCoreEventClass, kAEQuitApplication,
- &address, kAutoGenerateReturnID, kAnyTransactionID,
- &message));
- CATCHERROR(AESend(&message, &reply,
- kAENoReply + kAENeverInteract + kAEDontRecord,
- kAEHighPriority, kAEDefaultTimeout,
- (AEIdleUPP)kODNULL, (AEFilterUPP)kODNULL));
-
- cleanup:
- AEDisposeDesc(&address);
- AEDisposeDesc(&message);
- AEDisposeDesc(&reply);
-
- return error;
- }
-
- //------------------------------------------------------------------------------
- // HandleQuit
- //------------------------------------------------------------------------------
-
- static pascal OSErr HandleQuit( const AppleEvent*, AppleEvent*, long )
- {
- gRunning = false;
-
- return noErr;
- }
-
-